package nciae.db.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import nciae.db.common.CommonResult;
import nciae.db.mapper.*;
import nciae.db.pojo.entity.*;
import nciae.db.pojo.vo.ClassVO;
import nciae.db.pojo.vo.ExportVO;
import nciae.db.service.ClassService;
import nciae.db.service.ProjectService;
import nciae.db.utils.ExcelExportUtil;
import org.apache.ibatis.javassist.bytecode.stackmap.TypeData;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ClassServiceImpl extends ServiceImpl<ClassMapper, Classs> implements ClassService {


    @Autowired
    private ClassMapper classMapper;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private ExpertMapper expertMapper;


    /**
     * 分页查询班级信息
     *
     * @param className
     * @param chargerName
     * @param startDate
     * @param endDate
     * @param page
     * @param size
     * @return
     */
    @Override
    public CommonResult search(String className, String chargerName, String startDate, String endDate, Integer page, Integer size, HttpServletRequest request) {
        CommonResult<List<ClassVO>> rs = new CommonResult<>();
        try {

            DateTime start = null;
            DateTime end = null;
            if (startDate != null && !startDate.isEmpty() && endDate != null && !endDate.isEmpty()) {
                start = DateUtil.parse(startDate);  // 开始时间
                end = DateUtil.parse(endDate).offset(DateField.HOUR, 23).offset(DateField.MINUTE, 59).offset(DateField.SECOND, 59);  // 结束时间设置为当天的23:59:59
            }

            // 计算分页偏移量
            int offset = (page - 1) * size;
            User loginUser = (User)request.getSession().getAttribute("user");
            if("管理员".equals(loginUser.getRole())){
                // 调用 Mapper 中的查询方法
                List<ClassVO> classList = classMapper.selectClassesByProjectDateRange(className, chargerName, start, end, offset, size);

                // 查询班级总数
                long count = classMapper.countClassesByProjectDateRange(className, chargerName, start, end);

                // 设置查询结果
                rs.setCode(0);
                rs.setMsg("查询成功");
                rs.setCount(count);
                rs.setData(classList);
            }else if("班主任".equals(loginUser.getRole())){
                QueryWrapper<Classs> wrapper = new QueryWrapper<>();
                wrapper.eq("charger_id", loginUser.getId());
                List<Classs> classses = classMapper.selectList(wrapper);
                ArrayList<ClassVO> list = new ArrayList<>();
                for (Classs classs : classses){
                    ClassVO classVO = new ClassVO();
                    BeanUtils.copyProperties(classs, classVO);
                    Integer projectId = classs.getProjectId();
                    Project project = projectMapper.selectById(projectId);
                    classVO.setProjectName(project.getProjectName());
                    list.add(classVO);
                }
                // 设置查询结果
                rs.setCode(0);
                rs.setMsg("查询成功");
                rs.setCount(list.size());
                rs.setData(list);
            }
            return rs;
        } catch (Exception e) {
            rs.setCode(-1);
            rs.setMsg("发生错误: " + e.getMessage());
            return rs;
        }
    }

        @Override
        public CommonResult<List<String>> listClassName() {
            CommonResult<List<String>> rs = new CommonResult<>();
            try {
                QueryWrapper<Classs> classsQueryWrapper = new QueryWrapper<>();
                classsQueryWrapper.select("class_name").groupBy("class_name");
                List<String> classNameList = classMapper.selectMaps(classsQueryWrapper).stream().map(map -> map.get("class_name").toString()).collect(Collectors.toList());
                rs.setCode(0);
                rs.setMsg("查询成功");
                rs.setData(classNameList);
                return rs;
            } catch (Exception e) {
                rs.setCode(-1);
                rs.setMsg("发生错误" + e.getMessage());
                return rs;
            }
        }
    @Override
    public CommonResult<List<String>> listChargerRelevance(String chargerName,String param) {
        CommonResult<List<String>> rs = new CommonResult<>();
        try {

            if ("class".equals(param)) {
                QueryWrapper<Classs> classsQueryWrapper = new QueryWrapper<>();

                classsQueryWrapper.select("class_name").groupBy("class_name").eq("charger_id", chargerName);
                List<String> classNameList = classMapper.selectMaps(classsQueryWrapper).stream()
                        .map(map -> map.get("class_name").toString())
                        .collect(Collectors.toList());
                rs.setCode(0);
                rs.setMsg("查询成功");
                rs.setData(classNameList);
            } else if ("project".equals(param)) {
                QueryWrapper<Classs> classsQueryWrapper = new QueryWrapper<>();
                classsQueryWrapper.select("project_id").groupBy("project_id").eq("charger_id", chargerName);
                List<Object> projectIdList = classMapper.selectMaps(classsQueryWrapper).stream()
                        .map(map -> map.get("project_id"))
                        .collect(Collectors.toList());
                List<String> projectNameList = new ArrayList<>();
                if (!projectIdList.isEmpty()) {
                    QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
                    projectQueryWrapper.in("id", projectIdList);
                    projectNameList = projectMapper.selectList(projectQueryWrapper).stream()
                            .map(Project::getProjectName)
                            .collect(Collectors.toList());
                }
                rs.setCode(0);
                rs.setMsg("查询成功");
                rs.setData(projectNameList);
            } else {
                rs.setCode(-1);
                rs.setMsg("Invalid param value: " + param);
                return rs;
            }
        } catch (Exception e) {
            rs.setCode(-1);
            rs.setMsg("发生错误：" + e.getMessage());
            // 这里可以添加日志记录，例如使用日志框架
            // logger.error("Error occurred in listChargerClass method", e);
        }
        return rs;
    }

    @Override
    public CommonResult<List<String>> listAllRelevance(String param) {
        CommonResult<List<String>> rs = new CommonResult<>();
        try {
            if ("class".equals(param)) {
                QueryWrapper<Classs> classsQueryWrapper = new QueryWrapper<>();
                classsQueryWrapper.select("class_name").groupBy("class_name");
                List<String> classNameList = classMapper.selectMaps(classsQueryWrapper).stream()
                        .map(map -> map.get("class_name").toString())
                        .collect(Collectors.toList());
                rs.setCode(0);
                rs.setMsg("查询成功");
                rs.setData(classNameList);
            } else if ("project".equals(param)) {
                QueryWrapper<Classs> classsQueryWrapper = new QueryWrapper<>();
                classsQueryWrapper.select("project_id").groupBy("project_id");
                List<Object> projectIdList = classMapper.selectMaps(classsQueryWrapper).stream()
                        .map(map -> map.get("project_id"))
                        .collect(Collectors.toList());
                List<String> projectNameList = new ArrayList<>();
                if (!projectIdList.isEmpty()) {
                    QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
                    projectQueryWrapper.in("id", projectIdList);
                    projectNameList = projectMapper.selectList(projectQueryWrapper).stream()
                            .map(Project::getProjectName)
                            .collect(Collectors.toList());
                }
                rs.setCode(0);
                rs.setMsg("查询成功");
                rs.setData(projectNameList);
            } else {
                rs.setCode(-1);
                rs.setMsg("Invalid param value: " + param);
                return rs;
            }
        } catch (Exception e) {
            rs.setCode(-1);
            rs.setMsg("发生错误：" + e.getMessage());
            // 这里可以添加日志记录，例如使用日志框架
            // logger.error("Error occurred in listChargerClass method", e);
        }
        return rs;
    }

    @Override
    public boolean removeClass(Integer classId) {
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("class_id", classId);
        List<Student> studentList = studentMapper.selectList(queryWrapper);
        if (studentList.isEmpty()) {
            classMapper.deleteById(classId);
            return true;
        }
        return false;
    }

    @Override
    public  CommonResult<Integer> findClassNum(String className) {
        CommonResult<Integer> rs = new CommonResult<>();
        try {
            // 从班级表中根据班级名称查询班级 ID
            QueryWrapper<Classs> classQueryWrapper = new QueryWrapper<>();
            classQueryWrapper.select("num").eq("class_name", className);
            List<Classs> classList = classMapper.selectList(classQueryWrapper);
            if (classList.isEmpty()) {
                rs.setCode(-1);
                rs.setMsg("未找到该班级");
                return rs;
            }
            // 每个班级只有一个记录，获取班级人数
            Classs classInfo = classList.get(0);
            Integer num = classInfo.getNum();
            rs.setCode(0);
            rs.setMsg("查询成功");
            rs.setData(num);
            return rs;
        } catch (Exception e) {
            rs.setCode(-1);
            rs.setMsg("发生错误: " + e.getMessage());
            return rs;
        }
    }

    @Override
    public CommonResult<List<String>> getProjectsByClass(String selectedClass) {
        CommonResult<List<String>> rs = new CommonResult<>();
        try {
            // 从班级表中根据班级名称查询项目 ID
            QueryWrapper<Classs> classQueryWrapper = new QueryWrapper<>();
            classQueryWrapper.select("project_id").eq("class_name", selectedClass);
            List<Classs> classList = classMapper.selectList(classQueryWrapper);
            if (classList.isEmpty()) {
                rs.setCode(-1);
                rs.setMsg("未找到该班级");
                return rs;
            }
            // 提取项目 ID 列表
            List<Integer> projectIdList = classList.stream()
                    .map(Classs::getProjectId)
                    .collect(Collectors.toList());
            // 从项目表中根据项目 ID 列表查询项目名称
            QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
            projectQueryWrapper.in("id", projectIdList);
            List<Project> projectList = projectMapper.selectList(projectQueryWrapper);
            if (projectList.isEmpty()) {
                rs.setCode(-1);
                rs.setMsg("未找到相关项目");
                return rs;
            }
            // 提取项目名称列表
            List<String> projectNameList = projectList.stream()
                    .map(Project::getProjectName)
                    .collect(Collectors.toList());


            rs.setCode(0);
            rs.setMsg("查询成功");
            rs.setData(projectNameList);
            return rs;


        } catch (Exception e) {
            rs.setCode(-1);
            rs.setMsg("发生错误: " + e.getMessage());
            return rs;
        }
    }

    @Override
    public CommonResult<List<String>> getClassesByProject(String selectedProject,Integer chargerId) {
        CommonResult<List<String>> rs = new CommonResult<>();
        try {
            // 从项目表中根据项目名称查询项目 ID
            QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
            projectQueryWrapper.select("id").eq("project_name", selectedProject);
            List<Project> projectList = projectMapper.selectList(projectQueryWrapper);
            if (projectList.isEmpty()) {
                rs.setCode(-1);
                rs.setMsg("未找到该项目");
                return rs;
            }
            // 提取项目 ID 列表
            List<Integer> projectIdList = projectList.stream()
                    .map(Project::getId)
                    .collect(Collectors.toList());
            // 从班级表中根据项目 ID 列表查询班级名称
            QueryWrapper<Classs> classQueryWrapper = new QueryWrapper<>();
            classQueryWrapper.select("class_name").in("project_id", projectIdList).eq("charger_id", chargerId);;
            List<Classs> classList = classMapper.selectList(classQueryWrapper);
            if (classList.isEmpty()) {
                rs.setCode(-1);
                rs.setMsg("未找到相关班级");
                return rs;
            }
            // 提取班级名称列表
            List<String> classNameList = classList.stream()
                    .map(Classs::getClassName)
                    .collect(Collectors.toList());
            rs.setCode(0);
            rs.setMsg("查询成功");
            rs.setData(classNameList);
            return rs;


        } catch (Exception e) {
            rs.setCode(-1);
            rs.setMsg("发生错误: " + e.getMessage());
            return rs;
        }
    }
    @Override
    public void exportClassStudents(Integer classId, HttpServletResponse response) throws IOException {
        try {
            // 查询班级成员数据
            List<Student> students = studentMapper.selectList(new QueryWrapper<Student>().eq("class_id", classId));

            if (students.isEmpty()) {
                throw new IllegalArgumentException("当前班级没有学员数据，无法导出");
            }

            // 预加载项目名称和专家名称，避免重复查询
            Map<Integer, String> projectNameMap = projectMapper.selectList(null).stream()
                    .collect(Collectors.toMap(Project::getId, Project::getProjectName, (v1, v2) -> v1));
            Map<Integer, String> expertNameMap = expertMapper.selectList(null).stream()
                    .collect(Collectors.toMap(Expert::getId, Expert::getName, (v1, v2) -> v1));

            // 转换为 ExportVO
            List<ExportVO> exportVOList = students.stream().map(student -> {
                ExportVO exportVO = new ExportVO();
                try {
                    log.info("打印");
                    // 复制基本属性
                    BeanUtils.copyProperties( student,exportVO);

                    // 设置项目名称和专家名称（避免 NPE）
                    exportVO.setProjectName(projectNameMap.getOrDefault(student.getProjectId(), "未知项目"));
                    exportVO.setExpertName(expertNameMap.getOrDefault(student.getExpertId(), "未知专家"));
                } catch (Exception e) {
                    log.error("转换 ExportVO 失败，学员 ID: {}", student.getId(), e);
                }
                return exportVO;
            }).collect(Collectors.toList());

            // 调用工具类生成 Excel 文件
            Workbook workbook = ExcelExportUtil.exportClassStudents(exportVOList);

            // 设置响应头并输出文件
            String className = classMapper.selectById(classId).getClassName();//获取班级名称
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(className+"名单.xlsx", "UTF-8"));

            try (ServletOutputStream outputStream = response.getOutputStream()) {
                workbook.write(outputStream);
            } finally {
                workbook.close();
            }
        } catch (Exception e) {
            log.error("导出班级成员 Excel 失败，班级 ID: {}", classId, e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            response.getWriter().write("导出班级成员失败，请稍后重试！");
        }
    }


}
